package com.qingfeng.auth.controller;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.qingfeng.base.controller.BaseController;
import com.qingfeng.base.entity.QueryRequest;
import com.qingfeng.framework.exception.BizException;
import com.qingfeng.auth.entity.Rsacert;
import com.qingfeng.license.AbstractServerInfos;
import com.qingfeng.license.LicenseCheckModel;
import com.qingfeng.license.LinuxServerInfos;
import com.qingfeng.license.WindowsServerInfos;
import com.qingfeng.system.entity.UserOrganize;
import com.qingfeng.auth.service.IRsacertService;
import com.qingfeng.system.service.IUserOrganizeService;
import com.qingfeng.system.service.IUserService;
import com.qingfeng.utils.*;
import lombok.extern.slf4j.Slf4j;
import net.sf.json.util.JSONUtils;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @ProjectName RsacertController
 * @author Administrator
 * @version 1.0.0
 * @Description 认证授权-rsa认证授权证书
 * @createTime 2022/1/19 0019 22:52
 */
@Slf4j
@Validated
@RestController
@RequestMapping("/auth/rsacert")
public class RsacertController extends BaseController {

    @Autowired
    private IRsacertService rsacertService;
    @Autowired
    private IUserService userService;
    @Autowired
    private IUserOrganizeService userOrganizeService;

    /**
     * @title listPage
     * @description 查询数据列表
     * @author Administrator
     * @updateTime 2022/1/19 0019 22:52
     */
    @GetMapping("/listPage")
    @PreAuthorize("hasAnyAuthority('rsacert:info')")
    public MyResponse listPage(QueryRequest queryRequest, Rsacert rsacert) {
        String userParams = SecurityContextHolder.getContext().getAuthentication().getName();
        //处理数据权限
        String user_id = userParams.split(":")[1];
        UserOrganize uoParam = new UserOrganize();
        uoParam.setUser_id(user_id);
        UserOrganize userOrganize = userOrganizeService.findUserOrganizeInfo(uoParam);
        List<String> auth_organize_ids = new ArrayList<String>();
        if(Verify.verifyIsNotNull(userOrganize)){
            if(Verify.verifyIsNotNull(userOrganize.getAuthOrgIds())){
                auth_organize_ids = Arrays.asList(userOrganize.getAuthOrgIds().split(","));
            }
        }
        rsacert.setAuth_user(user_id);
        rsacert.setAuth_organize_ids(auth_organize_ids);
        Map<String, Object> dataTable = MyUtil.getDataTable(rsacertService.findListPage(rsacert, queryRequest));
        return new MyResponse().data(dataTable);
    }

    /**
     * @title save
     * @description 保存数据
     * @author Administrator
     * @updateTime 2022/1/19 0019 22:53
     */
    @PostMapping
    @PreAuthorize("hasAnyAuthority('rsacert:add')")
    public void save(@Valid @RequestBody Rsacert rsacert,HttpServletResponse response) throws Exception {
        Json json = new Json();
        try {
            // 创建用户
            String id = GuidUtil.getUuid();
            rsacert.setId(id);
            String time = DateTimeUtil.getDateTimeStr();
            rsacert.setCreate_time(time);
            rsacert.setStatus("0");
            rsacert.setType("1");
            //处理数据权限
            String authParams = SecurityContextHolder.getContext().getAuthentication().getName();
            rsacert.setCreate_user(authParams.split(":")[1]);
            rsacert.setCreate_organize(authParams.split(":")[2]);

            Map map = RSAUtils.genKeyPair();
            rsacert.setPublicKey(map.get("RSAPublicKey")+"");
            rsacert.setPrivateKey(map.get("RSAPrivateKey")+"");

            this.rsacertService.save(rsacert);
            json.setSuccess(true);
            json.setMsg("新增信息成功");
        } catch (Exception e) {
            String message = "新增信息失败";
            json.setSuccess(false);
            json.setMsg(message);
            log.error(message, e);
            throw new BizException(message);
        }
        this.writeJson(response,json);
    }

    /**
     * @title update
     * @description 更新数据
     * @author Administrator
     * @updateTime 2022/1/19 0019 22:53
     */
    @PutMapping
    @PreAuthorize("hasAnyAuthority('rsacert:edit')")
    public void update(@Valid @RequestBody Rsacert rsacert,HttpServletResponse response) throws Exception {
        Json json = new Json();
        try {
            // 更新组织信息
            String time = DateTimeUtil.getDateTimeStr();
            rsacert.setUpdate_time(time);
            String authParams = SecurityContextHolder.getContext().getAuthentication().getName();
            rsacert.setUpdate_user(authParams.split(":")[1]);
            this.rsacertService.updateById(rsacert);
            json.setSuccess(true);
            json.setMsg("修改信息成功");
        } catch (Exception e) {
            String message = "修改信息失败";
            json.setSuccess(false);
            json.setMsg(message);
            log.error(message, e);
            throw new BizException(message);
        }
        this.writeJson(response,json);
    }

    /**
     * @title delete
     * @description 删除数据
     * @author Administrator
     * @updateTime 2022/1/19 0019 22:53
     */
    @DeleteMapping("/{ids}")
    @PreAuthorize("hasAnyAuthority('rsacert:del')")
    public void delete(@NotBlank(message = "{required}") @PathVariable String ids,HttpServletResponse response) throws Exception {
        Json json = new Json();
        try {
            String[] del_ids = ids.split(StringPool.COMMA);
            this.rsacertService.removeByIds(Arrays.asList(del_ids));
            json.setSuccess(true);
            json.setMsg("删除信息成功");
        } catch (Exception e) {
            String message = "删除信息失败";
            json.setSuccess(false);
            json.setMsg(message);
            log.error(message, e);
            throw new BizException(message);
        }
        this.writeJson(response,json);
    }

    /**
     * @title updateStatus
     * @description 更新状态
     * @author Administrator
     * @updateTime 2022/1/19 0019 22:53
     */
    @PostMapping("/updateStatus")
    @PreAuthorize("hasAnyAuthority('rsacert:status')")
    public void updateStatus(@Valid @RequestBody Rsacert rsacert,HttpServletResponse response) throws Exception {
        Json json = new Json();
        try {
            this.rsacertService.updateById(rsacert);
            json.setSuccess(true);
            json.setMsg("状态修改成功");
        } catch (Exception e) {
            String message = "状态修改失败";
            json.setSuccess(false);
            json.setMsg(message);
            log.error(message, e);
            throw new BizException(message);
        }
        this.writeJson(response,json);
    }

    /**
     * @title list
     * @description 查询数据列表
     * @author Administrator
     * @updateTime 2022/1/19 0019 22:53
     */
    @GetMapping("/list")
    public MyResponse list(Rsacert rsacert) throws IOException  {
        //处理数据权限
        String userParams = SecurityContextHolder.getContext().getAuthentication().getName();
        String user_id = userParams.split(":")[1];
        PageData pd = new PageData();
        pd.put("user_id",user_id);
        PageData orgPd = userService.findUserOrganizeInfo(pd);
        List<String> auth_organize_ids = new ArrayList<String>();
        if(Verify.verifyIsNotNull(orgPd)){
            if(Verify.verifyIsNotNull(orgPd.get("authOrgIds"))){
                auth_organize_ids = Arrays.asList(orgPd.get("authOrgIds").toString().split(","));
            }
        }
        rsacert.setAuth_user(user_id);
        rsacert.setAuth_organize_ids(auth_organize_ids);
        List<Rsacert> list = rsacertService.findList(rsacert);
        return new MyResponse().data(list);
    }

    /**
     * 获取公钥和私钥
     * @param rsacert
     * @return
     * @throws Exception
     */
    @GetMapping("/rsaKey")
    public MyResponse rsaKey(Rsacert rsacert) throws Exception  {
        Map map = RSAUtils.genKeyPair();
        return new MyResponse().data(map);
    }

    /**
     * 导出证书
     * @param rsacert
     * @return
     * @throws IOException
     */
    @GetMapping("/downloadCert")
    public void downloadCert(Rsacert rsacert,HttpServletResponse response) throws Exception  {
        Rsacert info = rsacertService.getById(rsacert.getId());
        PageData p = new PageData();
        p.put("ipAddress",info.getIpAddress());
        p.put("macAddress",info.getMacAddress());
        p.put("cpuSerial",info.getCpuSerial());
        p.put("mainBoardSerial",info.getMainBoardSerial());
        p.put("start_time",info.getStart_time());
        p.put("end_time",info.getEnd_time());
        p.put("user_num",info.getUser_num());
        String val = RSAUtils.encrypt(JsonToMap.map2json(p),info.getPublicKey());
        String fileAddress = ParaUtil.localName+"cert/"+info.getId()+"/license.lic";
        byte[] bytes = val.getBytes();
        File file = new File(fileAddress);
        if (!file.getParentFile().exists()){
            file.getParentFile().mkdirs();
        }
        FileOutputStream fos = new FileOutputStream(file);
        FileUtils.writeByteArrayToFile(file, bytes);
        IOUtils.closeQuietly(fos);
        FileUtil.downFile(response,fileAddress,"license.lic");
    }


}
